
package com.trydofor.a9task.base.code.help;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.common.io.Files;
import com.google.common.io.Resources;
import com.trydofor.aloe.character.StringSb;
import com.trydofor.aloe.character.Template;
import com.trydofor.aloe.converter.DateTime;
import com.trydofor.aloe.exception.Exceptions;

/**
 * @author : Shi Rongjiu (www.trydofor.com)
 * @date : Dec 13, 2012
 * @see :
 */

public class SysCodeMaker {
    
    private static final String     TEXT_FILE = ".txt";
    private static final String     JAVA_FILE = ".java";
    private static final Charset    UTF8      = Charset.forName("UTF8");
    private static final FileFilter TEXT      = new FileFilter() {
                                            @Override
                                            public boolean accept(File f) {
                                                return f.isFile() && f.canRead() && f.getName().endsWith(TEXT_FILE);
                                            }
                                        };
    private static final Template     TEMPLATE  = Template.parse(getTemplate("SysCodeTemplate.txt"),true);
    
    public static String getTemplate(String name) {
        try {
            return Resources.toString(Resources.getResource(SysCodeMaker.class, name), UTF8);
        }
        catch (IOException e) {
            Exceptions.throwFakeException(e);
        }
        return "";
    }
    
    public File[] listText(String src, String pkg) {
        File dir = new File(src, StringSb.replace(pkg, ".", "/"));
        Exceptions.checkIllegalArgument(!dir.exists() || !dir.isDirectory());
        return dir.listFiles(TEXT);
    }
    
    public String makeJavaCode(String pkg, File txt) throws IOException {
        String ft = txt.getCanonicalPath();
        String jv = StringSb.replace(ft, TEXT_FILE, JAVA_FILE);
        File java = new File(jv);
        if (java.exists()) return "java file exists:" + jv;
        
        List<String> lines = Files.readLines(txt, UTF8);
        Map<String,Object> para = new HashMap<String,Object>();
        // head para
        para.put("package", pkg);
        para.put("yyyy-MM-dd", DateTime.ymdYmd(DateTime.ymdEpo(System.currentTimeMillis())));
        para.put("class", StringSb.replace(txt.getName(), TEXT_FILE, ""));
        List<Map<String,?>> codes = new ArrayList<Map<String,?>>();
        para.put("code", codes);
        
        int part = 0;
        Map<String,Object> code = null;
        List<Map<String,Object>> langs = null;
        for (String ln : lines) {
            if (StringSb.trimToNull(ln) == null) {
                continue;
            }

            int pos = ln.indexOf(":");
            if (pos < 0) {
                if (part == 0) {
                    String key = ln.trim().toUpperCase();
                    int idx = key.indexOf(".");
                    if(idx > 0){
                        String grp = key.substring(0,idx).toLowerCase();
                        key = key.substring(idx+1);
                        
                        para.put("group-key", key); // 1,2
                        para.put("group-reg", CodeHelp.nameUnder2Java(grp)); // 1,2
                    }else{
                        para.put("group-key", key); // 1,2
                        para.put("group-reg", "GroupRoot"); // 1,2
                    }
                    langs = new ArrayList<Map<String,Object>>();
                    para.put("group-lang", langs);
                }
                else{
                    code = new HashMap<String,Object>();
                    codes.add(code);
                    String key = ln.trim().toUpperCase();
                    code.put("key", key); // 1,2
                    code.put("seq", String.valueOf(part)); // 2
                    langs = new ArrayList<Map<String,Object>>();
                    code.put("lang", langs);
                }
                part ++;
            }else{
                Map<String,Object> lang = new HashMap<String,Object>();
                String l = ln.substring(0, pos).trim().toUpperCase();
                String t = ln.substring(pos + 1).trim();
                lang.put("lang", l); // 1,2
                lang.put("text", t); // 1,2
                int spt = t.indexOf("|");
                if (spt >= 0) {
                    String info = t.substring(spt + 1).trim();
                    t = t.substring(0, spt).trim();
                    lang.put("info", info); // 2
                    lang.put("text", t); // 1,2
                }
                langs.add(lang);
            }
        }

        Files.write(TEMPLATE.merge(para), java, UTF8);
        
        return null;
    }

    public boolean postCheckText(String... pkg) {
        return false;
    }
    
    public void text2Java(String src, String... pkgs) throws IOException {
        for (String pkg : pkgs) {
            File[] txts = listText(src, pkg);
            for (File txt : txts) {
                String err = makeJavaCode(pkg, txt);
                if (err != null) {
                    System.out.println(err);
                }
                else {
                    System.out.println("make java for:"
                                       + StringSb.replace(txt.getCanonicalPath(), TEXT_FILE, JAVA_FILE));
                }
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
        SysCodeMaker scm = new SysCodeMaker();
        scm.text2Java("./src/main/java/", "com.trydofor.a9task.base.code.sysd");
    }
}
